<template>
    <Transition :name="transitionName" @after-leave="destroyComponent" @enter="updateHeight">
        <div class="h-message" :class="{
            [`h-message--${type}`]: type,
            'is-close': showClose
        }" v-show="visible" :style="cssStyle" @mouseenter="clearTimer" @mouseleave="startTimer" ref="messageRef">
            <div class="h-message__content">
                <slot>
                    <render-vnode :vNode="message" v-if="message"></render-vnode>
                </slot>
            </div>
            <div class="h-message__close" v-if="showClose">
                <h-icon @click="visible = false" icon="xmark"></h-icon>
            </div>
        </div>
    </Transition>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import RenderVnode from '@/common/renderVNode';
import type { MessageProps } from './types'
import HIcon from '../Icon/HIcon.vue';
import { getLastBottonOffset } from "./method";
import useEventListener from '../../hooks/useEventListener'

const messageRef = ref<HTMLDivElement>()
const { transitionName = 'fade-up', type = 'info', duration = 3000, destroy, offset = 20, id, zIndex } = defineProps<MessageProps>()
const visible = ref(false)
// 当前Message高度
const height = ref(0)
// 上一个实例的最下边的坐标，第一个是0
const lastBottonOffset = computed(() => getLastBottonOffset(id))
// 当前元素使用的top
const currentTop = computed(() => offset + lastBottonOffset.value)
// 当前元素为下一个元素预留bottnOffset
const bottomOffset = computed(() => height.value + currentTop.value)
const cssStyle = computed(() => ({
    top: currentTop.value + 'px',
    zIndex,
}))

let timer: number
const startTimer = () => {
    if (duration == 0) {
        return
    }
    timer = setTimeout(() => {
        visible.value = false
    }, duration)
}

const clearTimer = () => {
    clearTimeout(timer)
}

// watch(visible, () => {
//     if (!visible.value) {
//         destroy()
//     }
// })

onMounted(async () => {
    visible.value = true
    startTimer()
    // await nextTick()
    // height.value = messageRef.value!.getBoundingClientRect().height
})

function destroyComponent() {
    destroy()
}
function updateHeight() {
    height.value = messageRef.value!.getBoundingClientRect().height
}

function keydown(e: Event) {
    const event = e as KeyboardEvent
    if (event.code === 'Escape') {
        visible.value = false
    }
}
useEventListener(document, 'keydown', keydown)

defineExpose({
    bottomOffset,
    visible
})

</script>

<style scoped>
@import url(style.css);
</style>